package com.gitee.deament.server.core.data;


import com.gitee.deament.core.exception.DataException;
import com.gitee.deament.server.core.data.datatype.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author deament
 */
public class DBData {
    Logger logger = LoggerFactory.getLogger(DBData.class);
    private volatile DBInnerData[] dbIndex;

    /**
     * 初始化 数据库
     *
     * @param dbnum 数据库个数
     */
    public void init(int dbnum) {
        dbIndex = new DBInnerData[dbnum];
        for (int i = 0; i < dbnum; i++) {
            DBInnerData dbInnerData = new DBInnerData(i);
            dbIndex[i] = dbInnerData;
        }

    }

    /**
     * 设置 字符类型数据
     *
     * @param db
     * @param key
     * @param value
     * @return
     */
    public boolean setStringData(int db, String key, Value<String> value) {

        Value<?> dbvalue = dbIndex[db].getData().get(key);
        if (dbvalue != null) {
            if (!(dbvalue instanceof Map)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }
        }
        dbIndex[db].getData().put(key, value);

        return true;
    }

    /**
     * 获得字符类型数据
     *
     * @param db
     * @param key
     * @return
     */
    public Value<String> getStringData(int db, String key) {
        return (Value<String>) dbIndex[db].getData().get(key);
    }

    /**
     * 设置hash 类型数据
     *
     * @param db
     * @param hash
     * @param field
     * @param value
     * @return
     */
    public boolean setHashData(int db, String hash, String field, String value) {

        Map<String, String> hashData = new HashMap<>();
        hashData.put(field, value);
        Value<Map<String, String>> data = new Value<>();
        Value<?> dbvalue = dbIndex[db].getData().get(hash);
        if (dbvalue != null) {
            if (!(dbvalue instanceof Map)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }
        }
        dbIndex[db].getData().put(hash, data);

        return true;
    }

    /**
     * 获取 hash 的所有值
     *
     * @param db
     * @param hash
     * @return
     */
    public Value<Map<String, String>> getHashData(int db, String hash) {
        return (Value<Map<String, String>>) dbIndex[db].getData().get(hash);
    }

    /**
     * 获取数据库多少个
     *
     * @return
     */
    public int getDBIndexSize() {
        return dbIndex.length;
    }


    public DBInnerData[] getDBInnerData() {
        return dbIndex;
    }


    /**
     * 获取Hash 类型的所有键
     *
     * @param db
     */
    public Set<String> getHashKeys(int db) {
        Set<String> allkeys = new HashSet<>();
        Enumeration<String> keys = dbIndex[db].getData().keys();


        if (keys.hasMoreElements()) {
            String key = keys.nextElement();
            if (dbIndex[db].getData().get(key).getValue() instanceof Map) {
                allkeys.add(key);
            }
        }
        return allkeys;
    }

    /**
     * 获取Hash 类型的所有键
     *
     * @param db
     */
    public Collection<String> getHashVals(int db, String hash) {

        Value<?> value = dbIndex[db].getData().get(hash);
        if (value instanceof Map) {
            return ((Map<String, String>) value).values();
        }
        return null;
    }

    /**
     * 设置 List 类型数据
     * @param db
     * @param key
     * @param values
     * @return
     */
    public boolean setListData(int db, String key, Value<List<String>> values) {

        dbIndex[db].getData().put(key, values);
        return true;
    }

    /**
     * 获取list的长度
     * @param db
     * @param key
     * @return
     */
    public int getListDataLength(int db,String key){

        Value dbValue = dbIndex[db].getData().get(key);
        if (dbValue != null) {
            if (!(dbValue.getValue() instanceof List)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }

           return ((List) dbValue.getValue()).size();
        }
        return 0;
    }

    /**
     * 获取List类型数据，如果该数据不是List类型 ，则会抛出异常
     * @param db
     * @param key
     * @return
     */
    public Value<List<String>> getList(int db,String key){
        Value dbValue = dbIndex[db].getData().get(key);
        if (dbValue != null) {
            if (!(dbValue.getValue() instanceof List)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }

            return dbValue;
        }
        return null;
    }
    /**
     * 获取Set类型数据，如果该数据不是Set类型 ，则会抛出异常
     * @param db
     * @param key
     * @return
     */
    public Value<Set<String>> getSet(int db,String key){
        Value dbValue = dbIndex[db].getData().get(key);
        if (dbValue != null) {
            if (!(dbValue.getValue() instanceof Set)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }

            return dbValue;
        }
        return null;
    }


    /**
     * 设置Set 数据
     * @param db
     * @param key
     * @param value
     * @return
     */
    public boolean setSetData(int db,String key,String value){
        Value<Set<String>> value1 = getSet(db,key);
        if(value==null){
            HashSet<String> valueSet = new HashSet<>();
            valueSet.add(value);
            value1=new Value<>();
            value1.setValue(valueSet);
            dbIndex[db].getData().put(key,value1);
        }
        else{
            value1.getValue().add(value);
            //基于jvm 所以无需再次设置 dbIndex[db].getData().put(key,value1);
        }
        return true;
    }
    public boolean setZSortSetData(int db,String key,ZSortSetMember member){
        Value<ZSortSet> value = getZSortSetData(db,key);
        if(value==null||value.getValue()==null){

            value= new Value<>();
            ZSortSet data=      new ZSortSet();
            data.setMember(member);
            value.setValue( data );
            dbIndex[db].getData().put(key,value);
        }
        else{
            value.getValue().setMember(member);

            //基于jvm 所以无需再次设置 dbIndex[db].getData().put(key,value1);
        }
        return true;
    }

    public Value<ZSortSet> getZSortSetData(int db, String key) {
        Value dbValue = dbIndex[db].getData().get(key);
        if (dbValue != null) {
            if (!(dbValue.getValue() instanceof ZSortSet)) {
                throw new DataException("WRONGTYPE Operation against a key holding the wrong kind of value");
            }

            return dbValue;
        }
        return null;
    }
}
